package com.ceshiren.mini.service.impl;

import com.ceshiren.mini.common.Constants;
import com.ceshiren.mini.converter.PlanConverter;
import com.ceshiren.mini.converter.TestCaseConverter;
import com.ceshiren.mini.dao.PlanMapper;
import com.ceshiren.mini.dao.TestcaseMapper;
import com.ceshiren.mini.dao.TestcasePlanRelMapper;
import com.ceshiren.mini.dto.PlanDTO;
import com.ceshiren.mini.dto.PlanTestCasesDTO;
import com.ceshiren.mini.dto.TestCaseDTO;
import com.ceshiren.mini.entity.Plan;
import com.ceshiren.mini.entity.Testcase;
import com.ceshiren.mini.entity.TestcasePlanRel;

import com.ceshiren.mini.service.PlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class PlanServiceImpl implements PlanService {

    private PlanMapper planMapper;
    private TestcaseMapper testCaseMapper;

    private TestcasePlanRelMapper testCasePlanRelMapper;
    private PlanConverter planConverter;
    private TestCaseConverter testCaseConverter;


    @Autowired
    public void setPlanMapper(PlanMapper planMapper) {
        this.planMapper = planMapper;
    }
    @Autowired
    public void setTestCaseMapper(TestcaseMapper testCaseMapper) {
        this.testCaseMapper = testCaseMapper;
    }
    @Autowired
    public void setTestCasePlanRelMapper(TestcasePlanRelMapper testCasePlanRelMapper) {
        this.testCasePlanRelMapper = testCasePlanRelMapper;
    }
    @Autowired
    public void setPlanConverter(PlanConverter planConverter) {
        this.planConverter = planConverter;
    }
    @Autowired
    public void setTestCaseConverter(TestCaseConverter testCaseConverter) {
        this.testCaseConverter = testCaseConverter;
    }

    //事务开启
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int createPlan(PlanDTO planDTO) {

        //实体类转换
        System.out.println("实体类转换planDTO"+planDTO);
        Plan plan = planConverter.planDTOForplan(planDTO);
        plan.setStatus(1);
        //创建之前查看是否已存在，根据任务名查看
        Plan plan1 = planMapper.selectOne(plan);
        System.out.println(plan1);
        //如果不存在 可以进行插入
        if(null == plan1){
            //用例IDlist [1,2]
            List<Integer> testCaseListId = planDTO.getTestcase_ids();
            //[1,2] 转换为 1,2,3,4 根据传入的list查找出来对象
            List<Testcase> testCases = getTestCases(testCaseListId);
            if(!testCases.isEmpty()){
                Plan plan2 = planConverter.planDTOForplan(planDTO);
                plan2.setStatus(Constants.STATUS_ONE);
                plan2.setCreateTime(new Date());
                plan2.setUpdateTime(new Date());

                //mvn -v mvn clean test
                //默认要执行的命令为 testcase对象中的用例数据值,拼接 并且前面加上 -Dtest=
                StringBuilder resultBuilder = new StringBuilder();
                for (int i = 0; i < testCases.size(); i++) {
                    Testcase testcase = testCases.get(i);
                    resultBuilder.append(testcase.getStep());

                    if (i < testCases.size() - 1) {
                        resultBuilder.append(",");
                    }
                }

                String command = "-Dtest=" + resultBuilder;
                System.out.println("插入的任务默认命令为：" + command);
                plan2.setCommand(command);
                System.out.println("创建测试计划_plan2:"+plan2);

                //插入测试计划
                int i = planMapper.insertUseGeneratedKeys(plan2);
                System.out.println("插入测试计划个数：" + i);

                //查看插入的测试计划ID
                int generatedKey = plan2.getId();
                // 假设主键属性为id
                System.out.println("generatedKey:"+generatedKey);

                //测试任务与测试用例对应关系添加
                List<TestcasePlanRel> testCasePlanRels = new ArrayList<>();
                //根据查询出来的 testcase 的ID插入测试任务对应的用例ID
                testCases.forEach(testCase -> {
                    TestcasePlanRel testCasePlanRel = new TestcasePlanRel();
                    testCasePlanRel.setPlanId(generatedKey);
                    testCasePlanRel.setTestcaseId(testCase.getId());
                    testCasePlanRels.add(testCasePlanRel);
                });
                System.out.println(testCasePlanRels);
                //数据库的批量插入

                //一个测试任务关联了几条有效的测试用例
                int insertList = testCasePlanRelMapper.insertList(testCasePlanRels);
                return insertList;
            }
        }else {
            System.out.println("当前测试计划已存在");
        }
        return 0;
    }

    private List<Testcase> getTestCases(List<Integer> testCaseListId) {
        //[1,2,3,4] 转换为 1,2,3,4
        String testCaseIds = testCaseListId
                .stream()
                //把每个Interger对象转换为字符串
                .map(String::valueOf)
                //1,2,3,4,5
                .collect(Collectors.joining(","));

        //ids – 如 "1,2,3,4"
        List<Testcase> testCases = testCaseMapper.selectByIds(testCaseIds);
        return testCases;
    }

    //获取单个的测试计划
    @Override
    public PlanTestCasesDTO getPlanTestCasesDTO(PlanTestCasesDTO planTestCasesDTO) {
        Plan plan = getPlan(planTestCasesDTO);
        //根据计划ID查询出来列表
        PlanTestCasesDTO planDTO1 = getTestTaskDTO(plan);
        System.out.println("根据计划ID查询出来列表:"+planDTO1);
        return planDTO1;
    }
    @Override
    public Plan getPlan(PlanTestCasesDTO planTestCasesDTO) {
        //1. planTestCasesDTO转换为plan
        Plan plan = planConverter.planTestCasesDTOForPlan(planTestCasesDTO);
        plan.setStatus(1);

        //2. Mapper查找具体的plan  测试计划
        plan = planMapper.selectOne(plan);
        System.out.println("plan--:"+plan);

        return plan;
    }

    private PlanTestCasesDTO getTestTaskDTO(Plan plan) {
        //从表中根据PlanId查出所有关联的CaseId
        //去关联表中查看用例列表ID
        Example testTaskCaseRel = new Example(TestcasePlanRel.class);
        Example.Criteria criteria = testTaskCaseRel.createCriteria();
        //声明的实体类属性
        criteria.andEqualTo("planId", plan.getId());
        List<TestcasePlanRel> testCasePlanRels = testCasePlanRelMapper.selectByExample(testTaskCaseRel);
        //每个测试任务对应的用例ID列表 23 [41,42
        System.out.println(testCasePlanRels);
        //获取当前任务的所有用例ID
        List<Integer> caseIdList = new ArrayList<>();
        testCasePlanRels.forEach(testCasePlanRel -> caseIdList.add(testCasePlanRel.getTestcaseId()));
        //[1,2,3] 获取所有测试用例
        List<Testcase> testCaseList = getTestCases(caseIdList);
        //testCases    testCasesDTO
        List<TestCaseDTO> testCaseDTOList = testCaseConverter.testCaseListForTestCaseDTOList(testCaseList);

        //任务拼接
        PlanTestCasesDTO planTestCasesDTO = planConverter.planForPlanTestCasesDTO(plan);
        planTestCasesDTO.setTestcases(testCaseDTOList);
        return planTestCasesDTO;
    }



    @Override
    public List<PlanTestCasesDTO> getPlanList() {
        List<PlanTestCasesDTO> planDTOList = new ArrayList<>();
        //获取所有的测试计划
        Plan plan1 = new Plan();
        plan1.setStatus(1);
        List<Plan> planList = planMapper.select(plan1);

        System.out.println(planList);
        //如果测试计划为空则返回null
        if(Objects.isNull(planList) || planList.isEmpty())
            return null;
        //测试计划遍历
        planList.forEach(plan -> {
            PlanTestCasesDTO planTestCasesDTO = getTestTaskDTO(plan);
            planDTOList.add(planTestCasesDTO);
        });
        System.out.println(planDTOList);

        return planDTOList;
    }

    @Override
    public int updatePlan(PlanDTO planDTO) {
        return 0;
    }

    @Override
    public int deletePlan(PlanDTO planTDO) {
        //查找测试用例
        //1. 转换
        Plan plan = planConverter.planDTOForplan(planTDO);
        plan.setStatus(1);
        //2. Mapper查找具体的plan
        plan = planMapper.selectOne(plan);

        //如果测试用例存在则删除
        if(null != plan){
            plan.setStatus(0);
            int update = planMapper.updateByPrimaryKey(plan);
            System.out.println("如果测试计划存在则删除:"+plan);
            return update;
        }
        //否则返回0
        return 0;
    }

}
